package com.sleepingrain;

import java.io.IOException;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class RainActivity extends SoundActivity implements SeekBar.OnSeekBarChangeListener
{
	RainGenerator m_gen;
	//RainGenerator m_gen2;
	ContinousGenerator m_gen3;
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.rain);
		initSoundUI();
		
		Button advButton = (Button)findViewById(R.id.bAdvanced);
		advButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				LinearLayout advLayout = (LinearLayout)findViewById(R.id.advLayout);
				if (advLayout.getVisibility() == View.GONE) 
					advLayout.setVisibility(View.VISIBLE);
				else 
					advLayout.setVisibility(View.GONE);
			}});
		
		sampleTimerHandler = new Handler();
		lastSampleTimerMillis = System.currentTimeMillis();
		sampleTimerHandler.removeCallbacks(sampleTimerTask);
		sampleTimerHandler.postDelayed(sampleTimerTask, sampleTimerInterval);

		final SampleLib nearRainLib = new SampleLib();
		nearRainLib.loadFromAssets(getAssets(), "RainNear", 44100,1);
		
		{
			Thread resamplerThread = new Thread(new Runnable() {
				public void run() {
					List<Sample> originals = nearRainLib.getOriginals();
					nearRainLib.addAll(Sample.resampleBy(originals, 55, 3));
					nearRainLib.addAll(Sample.resampleBy(originals, 60, 3));
					nearRainLib.addAll(Sample.resampleBy(originals, 65, 3));
					nearRainLib.addAll(Sample.resampleBy(originals, 70, 3));
					nearRainLib.addAll(Sample.resampleBy(originals, 85, 3));
					nearRainLib.addAll(Sample.resampleBy(originals, 125, 3));
					nearRainLib.addAll(Sample.resampleBy(originals, 110, 3));
					nearRainLib.addAll(Sample.resampleBy(originals, 115, 3));
					nearRainLib.addAll(Sample.resampleBy(originals, 120, 3));
				}
			});
			resamplerThread.setPriority(Thread.MIN_PRIORITY);
			resamplerThread.start();
		}
		
		m_gen = new RainGenerator(soundBuffer,nearRainLib);
		m_gen.title = "RainGen1";

		final SampleLib wetRainLib = new SampleLib();
		wetRainLib.loadFromAssets(getAssets(), "RainWet", 44100,1);
		
		{
			Thread resamplerThread = new Thread(new Runnable() {
				public void run() {
					List<Sample> originals = wetRainLib.getOriginals();
					wetRainLib.addAll(Sample.resampleBy(originals, 55, 3));
					wetRainLib.addAll(Sample.resampleBy(originals, 60, 3));
					wetRainLib.addAll(Sample.resampleBy(originals, 65, 3));
					wetRainLib.addAll(Sample.resampleBy(originals, 70, 3));
					wetRainLib.addAll(Sample.resampleBy(originals, 85, 3));
					wetRainLib.addAll(Sample.resampleBy(originals, 125, 3));
					wetRainLib.addAll(Sample.resampleBy(originals, 110, 3));
					wetRainLib.addAll(Sample.resampleBy(originals, 115, 3));
					wetRainLib.addAll(Sample.resampleBy(originals, 120, 3));
				}
			});
			resamplerThread.setPriority(Thread.MIN_PRIORITY);
			resamplerThread.start();
		}
		
		/*m_gen2 = new RainGenerator(soundBuffer,wetRainLib);
		m_gen2.title = "RainGen2";
	
		final SampleLib dryRainLib = new SampleLib();
		dryRainLib.loadFromAssets(getAssets(), "RainDry", 44100,1);
		
		{
			Thread resamplerThread = new Thread(new Runnable() {
				public void run() {
					List<Sample> originals = dryRainLib.getOriginals();
					dryRainLib.addAll(Sample.resampleBy(originals, 55, 3));
					dryRainLib.addAll(Sample.resampleBy(originals, 60, 3));
					dryRainLib.addAll(Sample.resampleBy(originals, 65, 3));
					dryRainLib.addAll(Sample.resampleBy(originals, 70, 3));
					dryRainLib.addAll(Sample.resampleBy(originals, 85, 3));
					dryRainLib.addAll(Sample.resampleBy(originals, 125, 3));
					dryRainLib.addAll(Sample.resampleBy(originals, 110, 3));
					dryRainLib.addAll(Sample.resampleBy(originals, 115, 3));
					dryRainLib.addAll(Sample.resampleBy(originals, 120, 3));
				}
			});
			resamplerThread.setPriority(Thread.MIN_PRIORITY);
			resamplerThread.start();
		}*/
		
		PinkNoiseGen pnoise = new PinkNoiseGen();
		final SampleLib noiseLib = new SampleLib();
		noiseLib.add(pnoise.prepareSample(5, 1.5, 44100, 3000));

		m_gen3 = new ContinousGenerator(soundBuffer,noiseLib);
		m_gen3.config_setVolume(100);

		/*m_gen3 = new RainGenerator(soundBuffer,dryRainLib);
		m_gen3.title = "RainGen3";
		m_gen3.config_setMinDistance(10);
		m_gen3.config_setVolume(5);
		//m_gen3.config_setCaching(true);
		m_gen3.config_setIntensity(75);
		m_gen3.config_setPitch(100);
		m_gen3.config_setRoomsize(10);*/
		
		initializeSeekbars();
		//Load settings
		loadSettings();

		final Thread rainThread = new Thread(m_gen, "dryThread");
		rainThread.start();
		/*final Thread bingThread = new Thread(m_gen2, "wetThread");
		bingThread.start();*/
		final Thread bgThread = new Thread(m_gen3, "bgThread");
		bgThread.start();
		playBackThread.start();
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		saveSettings();
	}
	
	SeekBar sbVolume;
	SeekBar sbBackgroundVolume;
	//SeekBar sbBackgroundIntensity;
	SeekBar sbDryDropIntensity;
	//SeekBar sbWetDropIntensity;
	SeekBar sbDryDropVolume;
	//SeekBar sbWetDropVolume;
	SeekBar sbRoomsize;
	SeekBar sbPitch;
	SeekBar sbStereoWidth;
	SeekBar sbTreble;
	SeekBar sbBass;
	
	protected void initializeSeekbars()
	{
		sbVolume = (SeekBar)findViewById(R.id.sbVolume);
		sbVolume.setOnSeekBarChangeListener(this);
		sbVolume.setProgress(getVolume());
		
		sbTreble = (SeekBar)findViewById(R.id.sbTreble);
		sbTreble.setOnSeekBarChangeListener(this);
		sbTreble.setProgress(getTreble());
		
		sbBass = (SeekBar)findViewById(R.id.sbBass);
		sbBass.setOnSeekBarChangeListener(this);
		sbBass.setProgress(getBass());
		
		sbBackgroundVolume = (SeekBar)findViewById(R.id.sbBackgroundVolume);
		sbBackgroundVolume.setOnSeekBarChangeListener(this);

/*		sbBackgroundIntensity = (SeekBar)findViewById(R.id.sbBackgroundIntensity);
		sbBackgroundIntensity.setOnSeekBarChangeListener(this);*/

		sbDryDropIntensity = (SeekBar)findViewById(R.id.sbDryDropIntensity);
		sbDryDropIntensity.setMax(80);
		sbDryDropIntensity.setOnSeekBarChangeListener(this);

		/*sbWetDropIntensity = (SeekBar)findViewById(R.id.sbWetDropIntensity);
		sbWetDropIntensity.setMax(20);
		sbWetDropIntensity.setOnSeekBarChangeListener(this);*/
		
		sbDryDropVolume = (SeekBar)findViewById(R.id.sbDryDropVolume);
		sbDryDropVolume.setOnSeekBarChangeListener(this);

		/*sbWetDropVolume = (SeekBar)findViewById(R.id.sbWetDropVolume);
		sbWetDropVolume.setOnSeekBarChangeListener(this);*/

		sbRoomsize = (SeekBar)findViewById(R.id.sbRoomsize);
		sbRoomsize.setOnSeekBarChangeListener(this);

		sbPitch = (SeekBar)findViewById(R.id.sbPitch);
		sbPitch.setOnSeekBarChangeListener(this);

		sbStereoWidth = (SeekBar)findViewById(R.id.sbStereoWidth);
		sbStereoWidth.setOnSeekBarChangeListener(this);
	}

	private static final String SETTINGS_NAME = "RainSettings";	

	protected void loadSettings()
	{
		SharedPreferences settings = getSharedPreferences(SETTINGS_NAME, 0);
		sbVolume.setProgress(settings.getInt("volume", 50));
		sbBackgroundVolume.setProgress(settings.getInt("bgvolume", 30));
		//sbBackgroundIntensity.setProgress(settings.getInt("bgintensity", 30));
		sbDryDropIntensity.setProgress(settings.getInt("drydropintensity", 20));
		//sbWetDropIntensity.setProgress(settings.getInt("wetdropintensity", 0));
		sbDryDropVolume.setProgress(settings.getInt("drydropvolume", 20));
		//sbWetDropVolume.setProgress(settings.getInt("wetdropvolume", 0));
		sbRoomsize.setProgress(settings.getInt("roomSize", 15));
		sbPitch.setProgress(settings.getInt("pitch", 100));
		sbStereoWidth.setProgress(settings.getInt("stereoWidth", 100));
	}

	protected void saveSettings()
	{
		SharedPreferences settings = getSharedPreferences(SETTINGS_NAME, 0);
		SharedPreferences.Editor editor = settings.edit();
		editor.putInt("volume", sbVolume.getProgress());
		editor.putInt("bgvolume", sbBackgroundVolume.getProgress());
		//editor.putInt("bgintensity", sbBackgroundIntensity.getProgress());
		editor.putInt("drydropintensity", sbDryDropIntensity.getProgress());
		//editor.putInt("wetdropintensity", sbWetDropIntensity.getProgress());
		editor.putInt("drydropvolume", sbDryDropVolume.getProgress());
		//editor.putInt("wetdropvolume", sbWetDropVolume.getProgress());
		editor.putInt("roomSize", sbRoomsize.getProgress());
		editor.putInt("pitch", sbPitch.getProgress());
		editor.putInt("stereoWidth", sbStereoWidth.getProgress());
		// Commit the edits!
		editor.commit();
	}
	
	private Handler sampleTimerHandler;
	private final int sampleTimerInterval = 1000;
	private long lastSampleTimerMillis = 0;
	private long lastSamples = 0;
	private long lastSampleValues = 0;
	
	String smartValue(double size)
	{
		String result = String.format("%.2f", size);
		int base = (int)Math.log10(size);
		switch (base) 
		{
			case 3:case 4:case 5 : result = String.format("%.2fk", size / (Math.pow(10,3)));break;
			case 6:case 7:case 8 : result = String.format("%.2fM", size / (Math.pow(10,6)));break; 
			case 9:case 10:case 11 : result = String.format("%.2fG", size / (Math.pow(10,9)));break;
			case 12:case 13:case 14 : result = String.format("%.2fT", size / (Math.pow(10,12)));break;
		}
		return result;
	}

	private Runnable sampleTimerTask = new Runnable() {
		public void run() {
			long now = System.currentTimeMillis();
			long delta = now - lastSampleTimerMillis;
			long samples = soundBuffer.totalSamples;
			long sampleValues = soundBuffer.totalSampleValues;
			TextView samples_tv = (TextView)findViewById(R.id.samplesPerSec);
			samples_tv.setText(String.valueOf((samples-lastSamples)*1000/delta)+" / "+
					smartValue((sampleValues-lastSampleValues)*1000/delta)+"\n\n"+
					soundBuffer.divisor+"\n\n");
			lastSampleTimerMillis = now;
			lastSamples = samples;
			lastSampleValues = sampleValues;
			sampleTimerHandler.postDelayed(this,sampleTimerInterval);
		}
	};

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
		switch(seekBar.getId())
		{
			case R.id.sbVolume:
				setVolume(progress);
				break;
			case R.id.sbTreble: 
				setTreble(progress); 
				break;
			case R.id.sbBass: 
				setBass(progress); 
				break;
			case R.id.sbBackgroundVolume:
            	m_gen3.config_setVolume(progress);
				break;
			/*case R.id.sbBackgroundIntensity:
            	m_gen3.config_setIntensity(progress);
				break;*/
			case R.id.sbDryDropIntensity:
            	m_gen.config_setIntensity(progress);
				break;
			/*case R.id.sbWetDropIntensity:
            	m_gen2.config_setIntensity(progress);
				break;*/
			case R.id.sbDryDropVolume:
				m_gen.config_setVolume(progress);
				break;
			/*case R.id.sbWetDropVolume:
				m_gen2.config_setVolume(progress);
				break;*/
			case R.id.sbPitch:
				m_gen.config_setPitch(progress);
				//m_gen2.config_setPitch(progress);
				break;
			case R.id.sbStereoWidth:
				m_gen.config_setStereoWidth(progress);
				//m_gen2.config_setStereoWidth(progress);
				break;
			case R.id.sbRoomsize:
            	m_gen.config_setRoomsize(progress);
            	//m_gen2.config_setRoomsize(progress);
				break;
		}
	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {

		showToast(seekBar.getProgress()+" %");
	}

	@Override
	public void startPlayer() {
		ivIcon.setImageResource(R.drawable.ic_pause);
		super.startPlayer();
	}

	@Override
	public void stopPlayer() {
		ivIcon.setImageResource(R.drawable.ic_play);
		super.stopPlayer();
	}

}
